#define __UC8159_C__

//#include "pindefine.h"
#include "UC8159.h"
//#include "Display_EPD_W21_spi.h"
//#include "stm32f1xx_hal.h"
//#include "LUT.h"
//#include "delay.h"
//#include "SPI.h"
//Ver. 3
#if 0
void setSdaIn(void) {
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.Pin = EPD_SDA_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(EPD_SDA_GPIO_Port, &GPIO_InitStruct);
}

void setSdaOut(void) {
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.Pin = EPD_SDA_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(EPD_SDA_GPIO_Port, &GPIO_InitStruct);
}

void check_busy_high(void)// If BUSYN=0 then waiting
{
while(!(BUSYN));
}

void check_busy_low(void)// If BUSYN=1 then waiting
{
while(BUSYN);
}

void spi_9b_init(void)
{
  SCL_L;
  SDA_H;
  CSB_H;
//  CSB1_H;
  BS_H;
  HAL_Delay(10);  // 5+(1+1)*6+3 = 20 us
}

unsigned char get_FPC_flash_vcom_data()
{
  unsigned char vcomFlashBuff = 0x1F;
  SPI_COMMAND(DAM);
  SPI_DATA(0x01);
  HAL_Delay(1000);
  ReadData_F(0x00,0x6400,&vcomFlashBuff,1);
  HAL_Delay(1000);
  SPI_COMMAND(DAM);
  SPI_DATA(0x00);
  
  return vcomFlashBuff;
}

unsigned char get_FPC_flash_pll_data()
{
  unsigned char pllFlashBuff[10];
  unsigned char tempFlashBuff[10];
  unsigned char pllData;
  unsigned char tempData;
  unsigned char tempData2;
  int LUT_idx;
  SPI_COMMAND(DAM);
  SPI_DATA(0x01);
  HAL_Delay(1000);
  ReadData_F(0x00,0x61AA,tempFlashBuff,10);
  ReadData_F(0x00,0x6410,pllFlashBuff,10);
  HAL_Delay(1000);
  SPI_COMMAND(DAM);
  SPI_DATA(0x00);
  HAL_Delay(1000);
  SPI_COMMAND(TSC);
  check_busy_high();
  tempData = SPI_GET_DATA();
  tempData2 = SPI_GET_DATA();
  tempData = tempData<<1;
  tempData2 = tempData2>>7;
  
  LUT_idx = (int)(tempData + tempData2);
  
  if(LUT_idx<tempFlashBuff[0])
  {
    pllData = pllFlashBuff[0];
  }
  else if(tempFlashBuff[0]<=LUT_idx && LUT_idx<tempFlashBuff[1])
  {
    pllData = pllFlashBuff[1];
  }
  else if(tempFlashBuff[1]<=LUT_idx && LUT_idx<tempFlashBuff[2])
  {
    pllData = pllFlashBuff[2];
  }
  else if(tempFlashBuff[2]<=LUT_idx && LUT_idx<tempFlashBuff[3])
  {
    pllData = pllFlashBuff[3];
  }
  else if(tempFlashBuff[3]<=LUT_idx && LUT_idx<tempFlashBuff[4])
  {
    pllData = pllFlashBuff[4];
  }
  else if(tempFlashBuff[4]<=LUT_idx && LUT_idx<tempFlashBuff[5])
  {
    pllData = pllFlashBuff[5];
  }
  else if(tempFlashBuff[5]<=LUT_idx && LUT_idx<tempFlashBuff[6])
  {
    pllData = pllFlashBuff[6];
  }
  else if(tempFlashBuff[6]<=LUT_idx && LUT_idx<tempFlashBuff[7])
  {
    pllData = pllFlashBuff[7];
  }
  else if(tempFlashBuff[7]<=LUT_idx && LUT_idx<tempFlashBuff[8])
  {
    pllData = pllFlashBuff[8];
  }
  else if(tempFlashBuff[8]<=LUT_idx)
  {
    pllData = pllFlashBuff[9];
  }
  
  
  SPI_COMMAND(PLL);
  SPI_DATA(pllData);
  
  return pllData;
}

void EPD_Init(void)
{
	unsigned char vcmData;
  spi_9b_init();
  RSTN_L; // Reset
  delay(3000);
  RSTN_H;
  delay(1000);

  spi_9b_send_9b(PON);
  check_busy_high();

  spi_9b_send_9b(EPDPWR);
  spi_9b_send(1,0x37);
  spi_9b_send(1,0x00);
  spi_9b_send(1,0x05);
  spi_9b_send(1,0x05);

  
  spi_9b_send_9b(PSR);//external flash
  spi_9b_send(1,0xCF);
  //spi_9b_send(1,0x08);
  
  SPI_COMMAND(0xe5);
  SPI_DATA(0x03);
  
  spi_9b_send_9b(PFS);
  spi_9b_send(1,0x00);
  
  spi_9b_send_9b(BTST);
  spi_9b_send(1,0xC7);
  spi_9b_send(1,0xCC);
  spi_9b_send(1,0x28);

  
  spi_9b_send_9b(PLL);
  spi_9b_send(1,0x3C);

  
  spi_9b_send_9b(TSE);
  spi_9b_send(1,0x00);

  spi_9b_send_9b(CDI);
  spi_9b_send(1,0x77);
  
  spi_9b_send_9b(TCON);
  spi_9b_send(1,0x22);
 
  spi_9b_send_9b(TRES);//600*448
  spi_9b_send(1,0x02);
  spi_9b_send(1,0x58);  
  spi_9b_send(1,0x01);
  spi_9b_send(1,0xC0);
  
  

  
  vcmData = get_FPC_flash_vcom_data();
  spi_9b_send_9b(VDCS);
  spi_9b_send(1, vcmData);

  spi_9b_send_9b(DAM);
  spi_9b_send(1,0x00);
  
  
  
  spi_9b_send_9b(POF);  

  PON_flag=0;
  
}

void power_saving(void)
{
	spi_9b_send_9b(DAM);
  spi_9b_send(1,0x01);
  Command_F(0xB9);
  spi_9b_send_9b(DAM);
  spi_9b_send(1,0x00);
        
  spi_9b_send_9b(DSLP);
  spi_9b_send(1,0xA5);
}

void out_of_power_saving(void)
{
	RSTN_L; // Reset
  delay(100);
  RSTN_H;
  
	spi_9b_send_9b(DAM);
  spi_9b_send(1,0x01);
  Command_F(0xAB);
  spi_9b_send_9b(DAM);
  spi_9b_send(1,0x00);
        
}

void EPD_Load_LUTC(unsigned int LUT, unsigned char const *LUT_Value)
{
  int i;  
  spi_9b_send_9b(LUT);
  for(i=0;i<220;i++) //Vcom WF data 220 bytes
  {
    spi_9b_send(DCX_DATA,*LUT_Value);
    LUT_Value++;
  }
}

void EPD_Load_LUTXON(unsigned int LUT, unsigned char const *LUT_Value)
{
  int i;  
  spi_9b_send_9b(LUT);
  for(i=0;i<200;i++) //XON WF data 200 bytes
  {
    spi_9b_send(DCX_DATA,*LUT_Value);
    LUT_Value++;
  }
}

void EPD_Load_LUT(unsigned int LUT, unsigned char const *LUT_Value)
{
  int i;  
  spi_9b_send_9b(LUT);
  for(i=0;i<260;i++) //WF data 260 bytes 
  {
    spi_9b_send(DCX_DATA,*LUT_Value);
    LUT_Value++;
  }
}

void CLEAR_LUT(void)
{
  spi_9b_send_9b(PON);
  check_busy_high();
  EPD_Load_LUT(LUT_VCOM1,lut_None);
  EPD_Load_LUT(LUT_WHITE,lut_None);
  EPD_Load_LUT(LUT_BLACK,lut_None);
  EPD_Load_LUT(LUT_RED0,lut_None);
  EPD_Load_LUT(LUT_RED1,lut_None); 
  EPD_Load_LUT(LUT_RED2,lut_None);
  EPD_Load_LUT(LUT_RED3,lut_None); 
  EPD_Load_LUT(LUT_XON,lut_None);
  spi_9b_send_9b(POF);  
  check_busy_low();
}

void Upload_Temperature_LUT(void)
{
/*
  EPD_Load_LUTC(LUT_VCOM1,lut_vcom1);
  EPD_Load_LUTXON(LUT_XON,lut_xon);
  EPD_Load_LUT(LUT_WHITE,lut_w);
  EPD_Load_LUT(LUT_BLACK,lut_b);
  EPD_Load_LUT(LUT_GRAY1,lut_g1);
  EPD_Load_LUT(LUT_GRAY2,lut_g2);
  EPD_Load_LUT(LUT_RED0,lut_red0);
  EPD_Load_LUT(LUT_RED1,lut_red1);
  EPD_Load_LUT(LUT_RED2,lut_red2);
  EPD_Load_LUT(LUT_RED3,lut_red3);
 */ 
}

void EPD_Display_White_Flash(void)
{
  unsigned long int i;
  
  out_of_power_saving();
  EPD_Init();
  
  get_FPC_flash_pll_data();
  
  spi_9b_send_9b(PON);
  check_busy_high();

  spi_9b_send_9b(DTM1);

  for(i=0;i<134400;i++)
  {
    spi_9b_send(1,0x33);
  }
  
  spi_9b_send_9b(DRF);
  check_busy_high();

  SPI_COMMAND(PSR);
  SPI_DATA(0xCF);
  SPI_DATA(0x0A);

  SPI_COMMAND(EPDPWR);
  SPI_DATA(0x02);
  SPI_DATA(0x00);
  SPI_DATA(0x00);
  SPI_DATA(0x00);
          
  delay(2000);
  
  spi_9b_send_9b(POF);  
  check_busy_low();
  
  delay(200);
  power_saving();
}



void EPD_Display_Black_Flash(void)
{
  unsigned long int i;
  
  out_of_power_saving();
  EPD_Init();
  
  get_FPC_flash_pll_data();
  spi_9b_send_9b(PON);
  check_busy_high();
  

  spi_9b_send_9b(DTM1);

  for(i=0;i<134400;i++)  //640x448 5.8" (640*448*4/8)
  {
    spi_9b_send(1,0x00);
  }
  
  spi_9b_send_9b(DRF);
  check_busy_high();
  
  SPI_COMMAND(PSR);
  SPI_DATA(0xCF);
  SPI_DATA(0x0A);

  SPI_COMMAND(EPDPWR);
  SPI_DATA(0x02);
  SPI_DATA(0x00);
  SPI_DATA(0x00);
  SPI_DATA(0x00);
          
  delay(2000);
  
  spi_9b_send_9b(POF);  
  check_busy_low();
  
  delay(200);
  power_saving();
}

void EPD_Display_Red_Flash(void)
{
  unsigned long int i;
  
  out_of_power_saving();
  EPD_Init();
  
  get_FPC_flash_pll_data();
  spi_9b_send_9b(PON);
  check_busy_high(); 
  
  
  spi_9b_send_9b(DTM1);

  for(i=0;i<134400;i++)
  {
    spi_9b_send(1,0x44);
  }
  
  spi_9b_send_9b(DRF);
  check_busy_high();
  
  SPI_COMMAND(PSR);
  SPI_DATA(0xCF);
  SPI_DATA(0x0A);

  SPI_COMMAND(EPDPWR);
  SPI_DATA(0x02);
  SPI_DATA(0x00);
  SPI_DATA(0x00);
  SPI_DATA(0x00);
          
  delay(2000);

  
  spi_9b_send_9b(POF);  
  check_busy_low();
  
  delay(200);
  power_saving();
}




void CSB_Low(void)
{
  CSB_L;
}

void CSB_High(void)
{
  CSB_H;
}

void spi_9b_send_9b(unsigned int dat)
{
  if((dat&DATA_MASK)==DATA_MASK) spi_9b_send(DCX_DATA,(unsigned char)dat);
  else spi_9b_send(DCX_CMD,(unsigned char)dat);
}


void SPI_COMMAND(unsigned char dat)
{
  unsigned char i;

  CSB_Low();
  
  delay(1);
  SDA_L; //0 for DCX_CMD
  SCL_H;
  delay(1);
  SCL_L;
  delay(1);    
  for(i=0;i<8;i++)
  {
    if(dat & 0x80) 
    {SDA_H;}
    else 
    {SDA_L;}
    delay(1);
    SCL_H;
    delay(1);    
    SCL_L;  
    dat=dat<<1;
  }
  SDA_L;
  delay(1);  
  
  CSB_High();
  
  delay(1);  
}

void SPI_DATA(unsigned char dat)
{
  unsigned char i;
  
  CSB_Low();
  
  delay(1);
  SDA_H; //1 for DCX_DATA
  SCL_H;
  delay(1);
  SCL_L;
  delay(1);    
  for(i=0;i<8;i++)
  {
    if(dat & 0x80) 
    {SDA_H;}
    else 
    {SDA_L;}
    delay(1);
    SCL_H;
    delay(1);    
    SCL_L;  
    dat=dat<<1;
  }
  SDA_L;
  delay(1);  
  
  CSB_High();
  
  delay(1);  
}

void spi_9b_send(unsigned int dcx,unsigned char dat)
{
  unsigned char i;
  
  CSB_Low();
  
  delay(1);
  if(dcx) SDA_H; //1 for DCX_DATA 
  else SDA_L; //0 for DCX_CMD
  SCL_H;
  delay(1);
  SCL_L;
  delay(1);    
  for(i=0;i<8;i++)
  {
    if(dat & 0x80) 
    {SDA_H;}
    else 
    {SDA_L;}
    delay(1);
    SCL_H;
    delay(1);    
    SCL_L;  
    dat=dat<<1;
  }
  SDA_L;
  delay(1);  
  
  CSB_High();
  
  delay(1);  
}

unsigned char SPI_GET_DATA(void)
{
  int i;
  unsigned char DATA_BUF=0x00;

  CSB_Low();

  delay(1);
  SDA_H; //1 for data
  delay(1);
  SCL_H;
  delay(1);
  SCL_L;
  delay(1);
  //P4DIR = 0x80;// SDA input
  setSdaIn();
  delay(3);   
  for(i=0;i<8;i++)
  {
    DATA_BUF=DATA_BUF<<1;
    SCL_H;
    if(SDA_IN) DATA_BUF|=0x01;     
    SCL_L;
    delay(1);
  }
  //P4DIR = 0xC0;// SDA output
  setSdaOut();
  SDA_L;
  
  delay(1);  
  
  CSB_High();
  
  delay(1);
  return DATA_BUF;
}

void setPON(unsigned char Flag)
{
  if(Flag==0)
  {
    spi_9b_send_9b(PON);
    check_busy_high();
    PON_flag=1;
  }
}

void setPOF(unsigned char Flag)
{
  if(Flag)
  {
    spi_9b_send_9b(POF);  
    check_busy_low();
    PON_flag=0;
  }
}

void send_SPI_DATA(unsigned char *data, unsigned int counter)
{
  unsigned int i;

  for(i=0;i<counter;i++)
  {
    SPI_DATA(*data);
    data++;
  }
}
#endif

